import { CloseOutlined } from '@ant-design/icons';
import { Button, Space } from 'antd';
import classNamesFn from 'classnames';
import React, { useMemo } from 'react';
import type { PanelProps } from '../../interface';

const Panel: React.FC<PanelProps> = (props) => {
  const {
    open,
    prefixCls,
    classNames,
    styles,
    ariaId,
    title,
    footer,
    closable = true,
    closeIcon,
    onClose,
    children,
    modalRender,
    onMouseDown,
    onMouseUp,
    holderRef,
    width,
    height,
    style,
    className,
    dialogStyle,
    onOk,
    onCancel,
    cancelText = '取消',
    okText = '确认',
  } = props;
  const {
    header: headerStyle,
    body: bodyStyle,
    footer: footerStyle,
  } = styles || {};
  const {
    header: headerClassName,
    body: bodyClassName,
    footer: footerClassName,
  } = classNames || {};

  const finalDialogStyle = useMemo(() => {
    let tempObj: React.CSSProperties = {};
    if (width) {
      tempObj.width = width;
    }
    if (height) {
      tempObj.height = height;
    }
    if (dialogStyle && Object.keys(dialogStyle).length > 0) {
      tempObj = { ...tempObj, ...dialogStyle };
    }
    return tempObj;
  }, [width, height]);

  // title
  const headerNode: React.ReactNode = useMemo(
    () =>
      title ? (
        <div
          className={classNamesFn(`${prefixCls}-header`, headerClassName)}
          style={headerStyle}
        >
          <div className={`${prefixCls}-title`} id={ariaId}>
            {title}
          </div>
        </div>
      ) : null,
    [title, headerClassName, headerStyle],
  );

  //footer 有回调事件，不能用useMemo, 如 onOk: () => { onChange?.(mergeValue || []) } 使用useMemo时 onOk是同一个函数，mergeValue也不会更新
  const footerNode: React.ReactNode =
    footer !== null ? (
      <div
        className={classNamesFn(`${prefixCls}-footer`, footerClassName)}
        style={footerStyle}
      >
        {footer || (
          <Space size={8}>
            <Button
              key="cancel"
              onClick={(e) => {
                onCancel?.(e);
              }}
            >
              {cancelText}
            </Button>
            <Button
              key="confirm"
              type="primary"
              onClick={(e) => {
                onOk?.(e);
              }}
            >
              {okText}
            </Button>
          </Space>
        )}
      </div>
    ) : null;
  //关闭icon
  const handleClose = (e: React.MouseEvent) => {
    e.stopPropagation();
    onClose(e);
  };

  const closer: React.ReactNode = closable ? (
    <button
      type="button"
      onClick={(e) => {
        handleClose(e);
      }}
      aria-label="Close"
      className={`${prefixCls}-close`}
    >
      {closeIcon || (
        <span className={`${prefixCls}-close-x`}>
          <CloseOutlined className={`${prefixCls}-close-icon`} />
        </span>
      )}
    </button>
  ) : null;

  const content = (
    <div className={`${prefixCls}-content`}>
      {closer}
      {headerNode}
      <div
        className={classNamesFn(`${prefixCls}-body`, bodyClassName)}
        style={bodyStyle}
      >
        {children}
      </div>
      {footerNode}
    </div>
  );

  return (
    <div
      key="dialog-element"
      role="dialog"
      aria-labelledby={title ? ariaId : undefined}
      aria-modal="true"
      ref={holderRef}
      style={{
        ...style,
        ...finalDialogStyle,
      }}
      className={classNamesFn(prefixCls, className)} // rc-dialog
      onMouseDown={onMouseDown}
      onMouseUp={onMouseUp}
    >
      {modalRender ? modalRender(content) : content}
    </div>
  );
};

export default Panel;
